package study.designpattern.simplefactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import study.designpattern.simplefactory.impl.ImpA;
import study.designpattern.simplefactory.impl.ImpB;

/**
 * 简单工厂类
 * 
 * 场景问题：客户端Client只知道要使用的Api接口，但不知道由谁实现，也不知道如何实现，从而得不到接口对象，
 *     就无法使用接口，该怎么办？
 * 解决方案：简单工厂：提供一个创建对象实例的功能，而无需关心其具体实现。被创建对象的类型可以是接口、抽象类，
 *     也可以是具体的类。
 *     
 * 简单工厂：提供一个创建对象实例的功能，而无需关心其具体实现。被创建对象的类型可以是接口、抽象类，也可以是具体的类。
 * 简单工厂的本质：实现选择
 * 
 * 何时选用简单工厂：
 *    1.如果想要完全封装隔离具体实现，让外部只能通过接口来操作封装体；
 *    2.如果想要把对外创建对象的职责集中管理和控制；
 * @author taowei20061122@163.com
 *
 */
public class SimpleFactory {
	/**
	 * 具体创建Api接口的方法，根据配置文件参数来创建接口
	 * @return
	 */
	public static Api getApi() {
		//直接读取配置文件来获取需要创建实例的类
		Properties properties = new Properties();
		
		InputStream in = SimpleFactory.class.getResourceAsStream("/impClassName.txt");
		
		try {
			properties.load(in);

		} catch (Exception e) {
			System.out.println("初始化配置文件出错");
			e.printStackTrace();
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		
		Api api = null;
		try {
			//反射
			api = (Api) Class.forName(properties.getProperty("impClass")).newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return api;
	}
	
	public static Api getApi(int condition) {
		Api api = null;
		if (1==condition) {
			api = new ImpA();
		} else {
			api = new ImpB();
		}
		return api;
	}
	
}
